package uy.com.tsi2G7.superbet.ui;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;

import uy.com.tsi2G7.superbet.account.Account;
import uy.com.tsi2G7.superbet.account.AccountService;
import uy.com.tsi2G7.superbet.pay.paypal.PayPalService;
import uy.com.tsi2G7.superbet.pay.paypal.PaypalFunctions;

@ManagedBean(name = "paypalBean")
@SessionScoped
public class PayPalBean {
	@EJB
	private PayPalService payPalService; 
	@EJB
	private AccountService accountService;
	@ManagedProperty(value="#{userBean}")
	private UserBean userBean;
	private String amount;
	private String userMail;
	private String userAmount;
	
	public String getAmount(){
		PaypalFunctions pf = new PaypalFunctions(payPalService);
		Map<String, String> requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
		String token = (String) requestMap.get("token");
		//Consultamos los datos al servidor
		HashMap nvp = pf.GetShippingDetails(token);
	    String strAck = nvp.get("ACK").toString();
		if(strAck !=null && !(strAck.equalsIgnoreCase("Success") || strAck.equalsIgnoreCase("SuccessWithWarning"))){
			this.showErrorMessage(nvp.get("").toString());
			return "0";
		}		
		amount = nvp.get("CUSTOM").toString();
		return amount;
	}
	
	public String confirmar() {
		try {		
			PaypalFunctions pf = new PaypalFunctions(payPalService);
			Map<String, String> requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
			String token = (String) requestMap.get("token");
			String payerID = (String) requestMap.get("payerID");
			String serverName = "";
			//Confirmamos el pago
			Map<String, String>  nvp = pf.ConfirmPayment(token, payerID,amount, serverName);
			String strAck = nvp.get("ACK").toString();
			if(strAck ==null || !strAck.equalsIgnoreCase("Success")){
				// Display a user friendly Error on the page using any of the following error information returned by PayPal
				//String ErrorCode = nvp.get("L_ERRORCODE0").toString();
				//String ErrorShortMsg = nvp.get("L_SHORTMESSAGE0").toString();
				//String ErrorLongMsg = nvp.get("L_LONGMESSAGE0").toString();
				//String ErrorSeverityCode = nvp.get("L_SEVERITYCODE0").toString();
				this.showErrorMessage(nvp.get("L_SHORTMESSAGE0").toString());
				return null;
			}
			//Creamos movimiento
			accountService.creditAmount(new BigDecimal(amount),userBean.getMail());			
			return "welcome";			
		} catch (Exception ex) {
			this.showErrorMessage(ex.getMessage());
			return null;
		}
	}
	
	public void validateAmountToTransfer(FacesContext context, UIComponent component, Object arg2) throws ValidatorException {
		try{ 
			if (((String) arg2).equals("")){
				throw new ValidatorException(new FacesMessage("Debe de ingresar un monto"));
			}
			double amount = new Double((String) arg2);
			//Se verifica que el monto sea mayor a cero y menor al monto disponible en la cuenta del usuario
			Account account = accountService.getAccount(userBean.getMail());
			if (amount <= 0) {
				throw new ValidatorException(new FacesMessage("El monto debe se mayor a cero"));
			}
			if (amount > account.getBalance().doubleValue()){
				throw new ValidatorException(new FacesMessage("El monto debe se menor o igual al saldo de su cuenta"));
			}
		}catch(ValidatorException e){
			throw e;
		}catch(Exception e){
			throw new ValidatorException(new FacesMessage(e.getMessage()));
		}
	}
	
	public String transferAmount(){
		try{
			PaypalFunctions pf = new PaypalFunctions(payPalService);
			Map<String, String>  nvp = pf.massPay(getUserMail(), getUserAmount());
			String strAck = nvp.get("ACK").toString();
			if(strAck ==null || !strAck.equalsIgnoreCase("Success")){
				// Display a user friendly Error on the page using any of the following error information returned by PayPal
				//String ErrorCode = nvp.get("L_ERRORCODE0").toString();
				//String ErrorShortMsg = nvp.get("L_SHORTMESSAGE0").toString();
				//String ErrorLongMsg = nvp.get("L_LONGMESSAGE0").toString();
				//String ErrorSeverityCode = nvp.get("L_SEVERITYCODE0").toString();
				this.showErrorMessage(nvp.get("L_SHORTMESSAGE0").toString());
				return null;
			}
			//Creamos movimiento
			accountService.debitAmount(new BigDecimal(getUserAmount()),userBean.getMail());			
			return "welcome";	
		}catch(Exception e){
			this.showErrorMessage(e.getMessage());
			return null;
		}
	}
	
	public String getCurrency(){
		try{
			return payPalService.getCurrency();
		} catch(Exception e){
			return "";
		}
	}
	
	private UIComponent getComponent(List<UIComponent> components, String id){
		Iterator<UIComponent> i = components.iterator();
		while(i.hasNext()){
			UIComponent component = i.next();
			if (component.getId().equals(id)){
				return component;
			}
		}
		return null;
	}

	
	public void showInformationMessage(String message) {
		if (message == null || "".equals(message.trim())) {
			message = "Error desconocido. Contacte al administrador";
		}
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, message, null));
	}

	public void showWarningMessage(String message) {
		if (message == null || "".equals(message.trim())) {
			message = "Error desconocido. Contacte al administrador";
		}
		FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, message, null));
	}

	public void showErrorMessage(String message) {
		if (message == null || "".equals(message.trim())) {
			message = "Error desconocido. Contacte al administrador";
		}
		FacesContext.getCurrentInstance()
				.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null));
	}
	
	public void setAmount(String amount) {
		this.amount = amount;
	}

	public UserBean getUserBean() {
		return userBean;
	}

	public void setUserBean(UserBean userBean) {
		this.userBean = userBean;
	}

	public String getUserMail() {
		return userMail;
	}

	public void setUserMail(String userMail) {
		this.userMail = userMail;
	}

	public String getUserAmount() {
		return userAmount;
	}

	public void setUserAmount(String userAmount) {
		this.userAmount = userAmount;
	}
    

}
